package cn.org.guhao.practice.go.util;

import cn.org.guhao.practice.go.model.WordCount;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;

public class WordUtils {

  public static Map<String,Long> allCountWords = new ConcurrentHashMap<>();

  public static Map<String,AtomicLong> wordCountAtomic = new ConcurrentHashMap<>();

  public static Map<String, LongAdder> wordCountLongAdder = new ConcurrentHashMap<>();

  public static synchronized void addCountWord(Map<String,Long> subCountWords){
    for(Map.Entry<String,Long> entry:subCountWords.entrySet()){
      if(allCountWords.containsKey(entry.getKey())){
        allCountWords.put(entry.getKey(), allCountWords.get(entry.getKey())+entry.getValue());
      }else {
        allCountWords.put(entry.getKey(), entry.getValue());
      }
    }
  }

  /**
   * 统计单词数量
   * @param words
   * @return
   */
  public static Map<String,Long> countWords(List<String> words){
    Map<String,Long> counts = new HashMap<>();
    for (String word:words){
      if(word == null || word.trim().equals(StringUtils.EMPTY)){
        continue;
      }
      long count = 1;
      word = word.toLowerCase();
      if(counts.containsKey(word)){
        count = counts.get(word) + 1;
      }
      counts.put(word,count);
    }
    return counts;
  }

  public static List<WordCount> convert(Map<String,Long> counts){
    List<WordCount> wordCountList = new ArrayList<>();
    for (Map.Entry<String,Long> entry:counts.entrySet()){
      String word = entry.getKey();
      if(word == null || word.trim().equals(StringUtils.EMPTY)){
        continue;
      }
      WordCount wordCount = new WordCount(word,entry.getValue());
      wordCountList.add(wordCount);
    }
    return wordCountList;
  }

  public static List<WordCount> convertAtomic(Map<String,AtomicLong> counts){
    List<WordCount> wordCountList = new ArrayList<>();
    for (Map.Entry<String,AtomicLong> entry:counts.entrySet()){
      String word = entry.getKey();
      if(word == null || word.trim().equals(StringUtils.EMPTY)){
        continue;
      }
      WordCount wordCount = new WordCount(word,entry.getValue().get());
      wordCountList.add(wordCount);
    }
    return wordCountList;
  }

  public static List<WordCount> convertLongAdder(Map<String,LongAdder> counts){
    List<WordCount> wordCountList = new ArrayList<>();
    for (Map.Entry<String,LongAdder> entry:counts.entrySet()){
      String word = entry.getKey();
      if(word == null || word.trim().equals(StringUtils.EMPTY)){
        continue;
      }
      WordCount wordCount = new WordCount(word,entry.getValue().longValue());
      wordCountList.add(wordCount);
    }
    return wordCountList;
  }

  /**
   * 原子加一统计单词
   * @param words
   */
  public static void increaseCountWord(List<String> words){
    for (String word:words){
      if(word == null || word.trim().equals(StringUtils.EMPTY)){
        continue;
      }
      AtomicLong count = wordCountAtomic.get(word);
      if(count == null){
        AtomicLong newCount = new AtomicLong(0);
        count = wordCountAtomic.putIfAbsent(word,newCount);
        if(null == count){
          count = newCount;
        }
      }
      count.incrementAndGet();
    }
  }

  /**
   * 原子加一统计单词
   * @param words
   */
  public static void addCountWord(List<String> words){
    for (String word:words){
      if(word == null || word.trim().equals(StringUtils.EMPTY)){
        continue;
      }
      LongAdder count = wordCountLongAdder.get(word);
      if(count == null){
        LongAdder newCount = new LongAdder();
        count = wordCountLongAdder.putIfAbsent(word,newCount);
        if(null == count){
          count = newCount;
        }
      }
      count.increment();
    }
  }

}
